package com.example.backend.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service

public class WeBASEUtils {

    @Value("${fisco.project.webase-Inurl}")
    String webaseUrl;

    @Value("${fisco.bcos.contracts.Account}")
    private String accountModuleAddress;
    @Value("${fisco.bcos.contracts.product}")
    private String productModuleAddress;
    @Value("${fisco.bcos.contracts.Order}")
    private String orderModuleAddress;
    @Value("${fisco.bcos.contracts.Logistic}")
    private String logisticsModuleAddress;
    @Value("${fisco.bcos.contracts.Receipt}")
    private String ReceiptModuleAddress;
    @Value("${fisco.bcos.userAddress}")
    private String userAddress;

    private final Map<String, String> contractAddressMap = new HashMap<>();
    private final Map<String, String> abiFileMap = new HashMap<>();

    @PostConstruct
    public void init() {
        // 合约key和application.yml中的字段保持一致，便于调用
        contractAddressMap.put("AccountModule", accountModuleAddress);
        contractAddressMap.put("ProductModule", productModuleAddress);
        contractAddressMap.put("OrderModule", orderModuleAddress);
        contractAddressMap.put("LogisticsModule", logisticsModuleAddress);
        contractAddressMap.put("ReceiptModule", ReceiptModuleAddress);

        // 约定key与ABI文件名的映射
        abiFileMap.put("AccountModule", "AccountModule.abi");
        abiFileMap.put("ProductModule", "ProductModule.abi");
        abiFileMap.put("OrderModule", "OrderModule.abi");
        abiFileMap.put("LogisticsModule", "LogisticsModule.abi");
        abiFileMap.put("ReceiptModule", "ReceiptModule.abi");
    }

    // 读取ABI文件内容
    private String loadAbi(String abiFileName) throws IOException {
        ClassPathResource resource = new ClassPathResource("abi/" + abiFileName);
        return new String(Files.readAllBytes(resource.getFile().toPath()), Charset.forName("UTF-8"));
    }

        /**
     * 通用上链方法（支持5个合约模块，动态选择）
     * @param contractKey 合约模块名: accountModule、productModule、orderModule、logisticsModule、ReceiptModule
     * @param funcName 方法名
     * @param funcParam 方法参数
     * @return 上链结果
     */
    public String funcPost( String contractKey, String funcName, List funcParam) {
       init();
        try {
            // 根据合约key获取对应的合约地址和ABI文件名
            System.out.println("ABI文件名: " + abiFileMap.get(contractKey));
            String contractAddress = contractAddressMap.get(contractKey);
            System.out.println("合约地址: " + contractAddress);
            String abiFileName = abiFileMap.get(contractKey);

            if (contractAddress == null || abiFileName == null) {
                throw new IllegalArgumentException("合约模块key不正确，支持的模块: AccountModule、ProductModule、OrderModule、LogisticsModule、ReceiptModule。当前: " + contractKey);
            }

            // 加载ABI内容并解析为JSON数组
            String contractAbi = loadAbi(abiFileName);

            JSONArray abiJSON = JSONUtil.parseArray(contractAbi);

            // 构造请求参数对象
            JSONObject data = JSONUtil.createObj();
            data.set("groupId", "1");
            data.set("contractPath", "/");
            data.set("contractAbi", abiJSON);
            data.set("useAes", false);
            data.set("useCns", false);
            data.set("cnsName", "");
            data.set("user", userAddress);
            data.set("contractAddress", contractAddress);
            data.set("funcName", funcName);
            data.set("funcParam", funcParam);

            // 将参数对象转换为JSON字符串
            String dataString = JSONUtil.toJsonStr(data);

            // 发起HTTP POST请求到WeBASE服务
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(webaseUrl);
            httpPost.setHeader("Content-type", "application/json;charset=utf-8");
            StringEntity entity = new StringEntity(dataString, Charset.forName("UTF-8"));
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

            // 执行HTTP请求并获取响应结果
            String result = null;
            try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
                // 解析响应结果
                result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
            }
            System.out.println(result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return "{\"code\":-1, \"message\":\"exception: " + e.getMessage() + "\"}";
        }
    }

}